using System;
using System.Collections.Generic;
using System.Linq;
using System.Xml;
using DataScripter.Scripting;

namespace DataScripter.XmlInterpreter.XmlInterpreters
{
    internal class TypesInterpreter : IXmlInterpreter<IDictionary<string, Type>>
    {
        private const string ELEMENT_NAME_TO_PROCESS = "Type";

        public IEngine Engine { get; set; }

        public TypesInterpreter(IEngine engine)
        {
            Engine = engine;
        }

        public IDictionary<string, Type> InterpretElement(XmlElement element)
        {
            IDictionary<string, Type> result = new Dictionary<string, Type>();
            foreach (XmlElement child in element.ChildNodes.OfType<XmlElement>())
            {
                switch (child.Name)
                {
                    case ELEMENT_NAME_TO_PROCESS:
                        InterpretType(child, result);
                        break;
                }
            }

            return result;
        }

        private void InterpretType(XmlElement xmlElement, IDictionary<string, Type> result)
        {
            string typeName = xmlElement.GetAttribute("Type");
            string typeIdentifier = xmlElement.GetAttribute("Name");
            Type type = Type.GetType(typeName, true);
            if (typeIdentifier == "")
                typeIdentifier = type.Name;

            Type interfaceType = GetInterfaceType(xmlElement);

            Engine.RegisterType(typeIdentifier, type, interfaceType);

            result.Add(typeIdentifier, type);
        }

        protected virtual Type GetInterfaceType(XmlElement xmlElement)
        {
            string interfaceName = xmlElement.GetAttribute("Interface");
            return interfaceName == "" ? null : Type.GetType(interfaceName, true);
        }
    }
}